#include "FaceRecognizer.h"

bool fr::FaceRecognizer::load_model(const std::string & init_nets, const std::string & predict_nets)
{
	return sphere_face->load_model(init_nets,predict_nets);
}

bool fr::FaceRecognizer::load_mean(const std::string & mean_file)
{
	return face_classifier->load_mean(mean_file);
}

void fr::FaceRecognizer::add_person(const std::string & name, const std::vector<float>& feature)
{
	assert(feature.size() == 1024);
	face_classifier->add_person(name, feature);
}

void fr::FaceRecognizer::add_person(const std::string & name, cv::Mat face_image, const std::vector<cv::Point2f>& face_landmarks)
{
	cv::Mat align_face;
	if (face_landmarks.empty())
	{
		align_face = face_image.clone();
		if (align_face.size() != cv::Size(FaceWidth, FaceHeight))
			cv::resize(align_face, align_face, cv::Size(FaceWidth, FaceHeight));
	}
	else
	{
		assert(face_landmarks.size() == 5);
		align_face = FaceAlignment::align_face(face_image, face_landmarks, FaceWidth, FaceHeight);
	}

	auto feature = sphere_face->extract_feature(align_face);
	face_classifier->add_person(name, feature);
}

std::pair<std::string, float> fr::FaceRecognizer::identify(const std::vector<float>& feature)const
{
	auto info = face_classifier->identify(feature);
	return make_pair(face_classifier->get_name(info.first), info.second);
}

std::pair<std::string, float> fr::FaceRecognizer::identify(cv::Mat face_image, const std::vector<cv::Point2f>& face_landmarks)const
{
	cv::Mat align_face;
	if (face_landmarks.empty())
	{
		align_face = face_image;
	}
	else
	{
		assert(face_landmarks.size() == 5);
		align_face = FaceAlignment::align_face(face_image, face_landmarks, FaceWidth, FaceHeight);
	}

	auto feature = sphere_face->extract_feature(align_face);
	auto info = face_classifier->identify(feature);
	return make_pair(face_classifier->get_name(info.first), info.second);
}

std::vector<float> fr::FaceRecognizer::extract_feature(cv::Mat face_image, const std::vector<cv::Point2f>& face_landmarks) const
{
	cv::Mat align_face;
	if (face_landmarks.empty())
	{
		align_face = face_image;
	}
	else
	{
		assert(face_landmarks.size() == 5);
		align_face = FaceAlignment::align_face(face_image, face_landmarks, FaceWidth, FaceHeight);
	}

	return sphere_face->extract_feature(align_face);
}
